package com.tpsix.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tpsix.domain.SysDept;
import com.tpsix.domain.SysMenu;
import com.tpsix.domain.SysRole;
import com.tpsix.domain.SysRoleDept;
import com.tpsix.domain.SysRoleMenu;
import com.tpsix.domain.SysUser;
import com.tpsix.domain.SysUserRole;
import com.tpsix.security.ProjectConfigurationProperties;
import com.tpsix.datascope.DataScopeContext;
import com.tpsix.security.saas.TenantContextHolder;
import com.tpsix.service.SysDeptService;
import com.tpsix.service.SysMenuService;
import com.tpsix.service.SysRoleDeptService;
import com.tpsix.service.SysRoleMenuService;
import com.tpsix.service.SysRoleService;
import com.tpsix.service.SysUserRoleService;
import com.tpsix.service.SysUserService;
import lombok.AllArgsConstructor;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tpsix.domain.SysTenant;
import com.tpsix.mapper.SysTenantMapper;
import com.tpsix.service.SysTenantService;
import org.springframework.transaction.annotation.Transactional;

@Service
@AllArgsConstructor
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements SysTenantService{

    private final SysDeptService sysDeptService;

    private final SysUserService sysUserService;

    private final SysRoleService sysRoleService;

    private final SysUserRoleService sysUserRoleService;

    private final SysMenuService sysMenuService;

    private final SysRoleMenuService sysRoleMenuService;

    private final SysRoleDeptService sysRoleDeptService;

    private final ProjectConfigurationProperties projectProperties;

    private final PasswordEncoder passwordEncoder;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveTenant(SysTenant sysTenant) {

        // 切换租户环境
        long beforeTenantId = TenantContextHolder.getTenantId();

        // 保存租户
        sysTenant.setCreateTime(LocalDateTime.now());
        sysTenant.setUpdateTime(LocalDateTime.now());
        this.save(sysTenant);
        TenantContextHolder.setTenantId(Long.valueOf(sysTenant.getId()));

        // 默认部门
        SysDept dept = new SysDept();
        dept.setName("默认部门");
        dept.setParentId(0);
        dept.setSort(0);
        dept.setCreateTime(LocalDateTime.now());
        dept.setUpdateTime(LocalDateTime.now());
        sysDeptService.save(dept);

        // 默认用户
        SysUser sysUser = new SysUser();
        sysUser.setUsername(projectProperties.getTenant().getDefaultUsername());
        sysUser.setPassword(passwordEncoder.encode(projectProperties.getTenant().getDefaultPassword()));
        sysUser.setDeptId(dept.getId());
        sysUserService.save(sysUser);

        // 默认角色
        SysRole sysRole = new SysRole();
        sysRole.setRoleName("默认角色");
        sysRole.setRoleCode("ROLE_ADMIN");
        // 本级及子级
        sysRole.setDsType(2);
        sysRole.setDsScope(String.valueOf(sysUser.getDeptId()));
        sysRoleService.save(sysRole);

        TenantContextHolder.setTenantId(beforeTenantId);

        // 用户角色关系
        SysUserRole userRole = new SysUserRole();
        userRole.setRoleId(sysRole.getId());
        userRole.setUserId(sysUser.getId());
        sysUserRoleService.save(userRole);

        // 角色部门关系
        SysRoleDept sysRoleDept = new SysRoleDept();
        sysRoleDept.setRoleId(sysRole.getId());
        sysRoleDept.setDeptId(dept.getId());
        sysRoleDeptService.save(sysRoleDept);

        // 所有菜单
        List<SysMenu> sysMenus = sysMenuService.list();

        // 配置租户默认菜单, 去除敏感菜单
        List<String> ignoreMenus = projectProperties.getTenant().getIgnoreMenus();
        if (CollectionUtil.isNotEmpty(ignoreMenus)) {
            ignoreMenus.forEach(item -> {
                sysMenus.removeIf(menu -> menu.getTitle().equals(item));
            });
        }

        // 角色菜单关系
        List<SysRoleMenu> sysRoleMenus = sysMenus.stream()
                .map(item -> {
                    SysRoleMenu sysRoleMenu = new SysRoleMenu();
                    sysRoleMenu.setRoleId(Long.valueOf(sysRole.getId()));
                    sysRoleMenu.setMenuId(Long.valueOf(item.getId()));
                    return sysRoleMenu;
                }).collect(Collectors.toList());

        return sysRoleMenuService.saveBatch(sysRoleMenus);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateTenant(SysTenant sysTenant) {
        long tenantId = TenantContextHolder.getTenantId();
        TenantContextHolder.setTenantId(Long.valueOf(sysTenant.getId()));
        this.updateById(sysTenant);
        SysDept dept = sysDeptService.getOne(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getName, sysTenant.getName()));
        dept.setName(sysTenant.getName());
        sysDeptService.updateById(dept);
        TenantContextHolder.setTenantId(tenantId);
        return true;
    }

}
